﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace app
{
    class Request
    {
        IPEndPoint RemoteEndPoint;

        byte[] Data = new byte[0];

        byte[] Address = new byte[0];

        RequestHeader Header;

        static internal void Send(Peer peer, byte[] address = null, byte[] data = null, RequestHeader header = null, RequestCommand command = 0)
        {
            Send(peer.IPEndPoint,
                address: address,
                data: data,
                header: header,
                command: command);
        }

        static internal void Send(IPEndPoint remoteEndPoint, byte[] address = null, byte[] data = null, RequestHeader header = null, RequestCommand command = 0)
        {
            Request o = new Request();

            o.RemoteEndPoint = remoteEndPoint;
            
            if (address != null)
                o.Address = address;

            if (data != null)
                o.Data = data;

            if (header == null)
            {
                o.Header = new RequestHeader(command);
            }
            else
                o.Header = header;

            o.Send();
        }

        void Send()
        {
            Log.Add("Send", RemoteEndPoint, Address);

            Data = Header.ToBytes().Concat(Address).Concat(Data).ToArray();

            ThreadPool.QueueUserWorkItem(new WaitCallback(this.ThreadSend), this);
        }

        void ThreadSend(object o)
        {
            Request req = (Request)o;

            UdpClient client = new UdpClient();

            client.Client.ExclusiveAddressUse = false;

            client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

            client.Client.Bind(new IPEndPoint(IPAddress.Any, Parameters.port));

            client.Send(req.Data, req.Data.Length, req.RemoteEndPoint);
        }
     
    }
}
